/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.ext.echarts.builder.impl;

import cn.easyplatform.web.ext.ComponentHandler;
import cn.easyplatform.web.ext.echarts.ECharts;
import cn.easyplatform.web.ext.echarts.lib.Option;
import com.google.gson.JsonArray;

import java.util.*;

public class ThreeDChartsBuilder extends AbstractChartsBuilder {

    private static final boolean DEBUG = false;

    public ThreeDChartsBuilder(String type) {
        super(type);
    }

    @Override
    protected void setSeries(Option option, String name, JsonArray data) {
        super.setSeries(option, name, data);
    }

    @Override
    public void build(ECharts charts, ComponentHandler dataHandler) {
        if (charts.getData() != null) {
            createData(charts);
        } else if (dataHandler == null) {
            build(charts.getOption(), getTemplate(charts.getTemplate()), true);
        } else if (charts.getOption().getDataset() != null) {
            createDataset(charts, dataHandler);
        } else if (charts.getQuery() != null) {
            List<Object[]> data =
                    dataHandler.selectList0(Object[].class, charts.getDbId(), (String) charts.getQuery());
            createModel(charts, data);
        } else {
            // Series是Map形式
            if (charts.getOption().getSeries() instanceof Map) {
                Map<String, Object> graph = (Map<String, Object>) charts.getOption().getSeries();
                if (graph.get("query") != null) {
                    List<Object[]> data =
                            dataHandler.selectList0(Object[].class, charts.getDbId(), (String) charts.getQuery());
                    createModel(charts, data);
                }
            }
            // Series是List形式
            else if (charts.getOption().getSeries() instanceof List) {
                List<?> series = (List<?>) charts.getOption().getSeries();
                Map<String, Object> graph = (Map<String, Object>) series.get(0);
                if (graph.get("query") != null) {
                    List<Object[]> data =
                            dataHandler.selectList0(Object[].class, charts.getDbId(), (String) charts.getQuery());
                    createModel(charts, data);
                }
            }
        }
    }

    private void createData(ECharts charts) {
        if (!(charts.getData() instanceof List)
                || ((List) charts.getData()).isEmpty()) {
            return;
        }
        Map series = null;
        if (charts.getOption().getSeries() instanceof Map) {
            series = (Map) charts.getOption().getSeries();
        } else if (charts.getOption().getSeries() instanceof List) {
            series = (Map) ((List) charts.getOption().getSeries()).get(0);
        }
        if (series != null) {
            series.put("data", charts.getData());
        }
        List itemList = (List) ((List) charts.getData()).get(0);
        if (itemList.get(0) instanceof String) { // 若x轴数据为字符串，则应为类别
            Map xAxis3D = (Map) charts.getOption().getxAxis3D();
            xAxis3D.put("type", "category");
        }
        if (itemList.get(1) instanceof String) { // 若y轴数据为字符串，则应为类别
            Map yAxis3D = (Map) charts.getOption().getyAxis3D();
            yAxis3D.put("type", "category");
        }
    }

    private void createModel(ECharts charts, List<Object[]> data) {
        if (data.isEmpty()) {
            charts.getOption().setSeries(setSeriesContent(charts, null));
        } else {
            charts.getOption().setSeries(setSeriesContent(charts, data));
        }
    }

    private Object setSeriesContent(ECharts charts, List<Object[]> data) {
        // Series以Map方式存在
        if (charts.getOption().getSeries() instanceof Map) {
            Map<String, Object> threeD = (Map<String, Object>) charts.getOption().getSeries();
        }
        // Series以List方式存在（主要）
        else if (charts.getOption().getSeries() instanceof List) {
            List<Map<String, Object>> seriesList = (List) charts.getOption().getSeries();
            if (seriesList.size() == 1) {  // Series列表里只有一条数据
                // 设置这一条的数据
                Map<String, Object> threeD = seriesList.get(0);
                threeD.put("data", formatData(data));
                seriesList.set(0, threeD);
                return seriesList;
            } else {  // Series列表里有多条数据
                // 暂待实现
                return charts.getOption().getSeries();
            }
        }
        return charts.getOption().getSeries();
    }

    /**
     * 格式化数据
     * 将数据整理为 [ [x1,y1,z1], [x2,y2,z2] ... ]的格式
     */
    private Object formatData(List<Object[]> data) {
        // 空数据处理
        if (data == null || data.size() <= 0) {
            return Collections.emptyList();
        } else {
            List<Object> formatList = new ArrayList<>();
            for (Object[] datum : data) {
                List<Object> valueList = new ArrayList<>();
                valueList.add(datum[0]);
                valueList.add(datum[1]);
                valueList.add(datum[2]);
                formatList.add(valueList);
            }
            return formatList;
        }
    }
}
